﻿


using Microsoft.AspNetCore.Mvc.Internal;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;


namespace NetCore
{
    public class CustomModelBinderProvider : IModelBinderProvider
    {
        public IModelBinder GetBinder(ModelBinderProviderContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }


            if (context.Metadata.ModelType.BaseType == typeof(EntityBase))
            {
                if (AppHttpContext.Current.Request.Method.Equals("POST", StringComparison.OrdinalIgnoreCase))
                {
                    EntityDbFactory action = new EntityDbFactory(context.Metadata.ModelType);
                    string key = action.EntityMap.PrimaryKey;
                    if (AppHttpContext.Current.Request.Form.ContainsKey(key) && !string.IsNullOrWhiteSpace(AppHttpContext.Current.Request.Form[key]))
                    {
                        return new BinderTypeModelBinder(typeof(CustomModelBinder));
                    }
                }
            }

            return null;
        }

      
    }


    public class CustomModelBinder : IModelBinder
    {
       

        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }
            var modelName = bindingContext.ModelName;
            EntityDbFactory action = new EntityDbFactory(bindingContext.ModelMetadata.ModelType);
            var model = ReflectionHelper.CreateInstance(bindingContext.ModelMetadata.ModelType);
            var valueProviderResult =
                bindingContext.ValueProvider.GetValue(action.EntityMap.PrimaryKey);
            // Try to fetch the value of the argument by name
            if (action == null || valueProviderResult == ValueProviderResult.None)
            {
               // bindingContext.Result = ModelBindingResult.Success(model);
                return Task.CompletedTask;
            }

            if (valueProviderResult == ValueProviderResult.None)
            {
                return Task.CompletedTask;
            }

            //bindingContext.ModelState.SetModelValue(modelName,
            //    valueProviderResult);

            var value = valueProviderResult.FirstValue;

            // Check if the argument value is null or empty
            if (string.IsNullOrEmpty(value))
            {
                return Task.CompletedTask;
            }

            //int id = 0;
            //if (!int.TryParse(value, out id))
            //{
            //    // Non-integer arguments result in model state errors
            //    bindingContext.ModelState.TryAddModelError(
            //                            modelName,
            //                            "Author Id must be an integer.");
            //    return Task.CompletedTask;
            //}

            // Model will be null if not found, including for 
            // out of range id values (0, -3, etc.)
             model = action.GetCache(value);
            if (model== null)
            {
                return Task.CompletedTask;
                // model = model1;
            }
            bindingContext.Result = ModelBindingResult.Success(model);
            return Task.CompletedTask;
        }
    }

    //public class CustomModelValidatorProvider : DefaultModelValidatorProvider
    //{
       
    //    //public void CreateValidators(ModelValidatorProviderContext context)
    //    //{
    //    //    string a = "b";
    //    //}

    //    //public IEnumerable<ModelValidationResult> Validate(ModelValidationContext context)
    //    //{
    //    //    return null;
    //    //}
    //}
}

